//
//  EWERequest.swift
//  EWEMDT3
//
//  Created by 来 on 2019/11/19.
//  Copyright © 2019 laiguofeng. All rights reserved.
//

import Foundation
import Alamofire
import CryptoSwift

typealias Succeed = (AnyObject) -> Void
typealias USucceed = (String) -> Void
typealias Failure = (String) -> Void

class EWERequest {
    
    static let session: Session = {
        let configuration = URLSessionConfiguration.default
        configuration.timeoutIntervalForRequest = 60
        let delegate = SessionDelegate.init()
        let serverTrustManager = ServerTrustManager.init(allHostsMustBeEvaluated: true, evaluators: [
            EWEUrl.BD_URL: DisabledTrustEvaluator()
        ])
        let session = Session.init(configuration: configuration, delegate: delegate, serverTrustManager: serverTrustManager)
        return session
    }()
    
    static func lgf(_ method: String!, _ paramet: [String: Any], _ type: HTTPMethod, _ encoding: ParameterEncoding = URLEncoding.default, _ succeed: @escaping Succeed, _ failed: @escaping Failure) {
        lgf(method, paramet, type, true, encoding, succeed, failed)
    }
    static func lgf(_ method: String!, _ paramet: [String: Any], _ type: HTTPMethod, _ hud: Bool , _ succeed: @escaping Succeed, _ failed: @escaping Failure) {
        lgf(method, paramet, type, hud, URLEncoding.default, succeed, failed)
    }
    static func lgf(_ method: String!, _ paramet: [String: Any], _ type: HTTPMethod, _ hud: Bool, _ encoding: ParameterEncoding = URLEncoding.default, _ succeed: @escaping Succeed, _ failed: @escaping Failure) {
        
        debugPrint("请求参数")
        debugPrint(paramet)
        
        let mysucceed: Succeed = succeed
        let myfailure: Failure = failed
        
        let isAES = EWEApi.lgf.SA && EWEUrl.lgf.AES
        var aes_paramet: [String: Any] = [:]
        if isAES {
            let key = Data.init(base64Encoded: "8vNlLhwaeIwMExGaM1ou9A==")!
            var encodedValue = ""
            if paramet.keys.contains("encryptedData") {
                encodedValue = (paramet["encryptedData"] as? String) ?? ""
                if encodedValue.count == 0 {
                    encodedValue = aesEncoded(String.lgf_JsonFrom(paramet["encryptedData"] as! [String: Any]), key)
                }
                paramet.forEach { (key, value) in
                    aes_paramet.updateValue(value, forKey: key)
                }
            } else {
                encodedValue = aesEncoded(String.lgf_JsonFrom(paramet), key)
            }
            aes_paramet.updateValue(encodedValue, forKey: "encryptedData")
            let timestamp = Date().lgf_TimeStampString()
            aes_paramet.updateValue((encodedValue + timestamp + "6FXyU8fU4uDP4ktOVDtFtg==").sha1(), forKey: "sign")
            aes_paramet.updateValue(timestamp, forKey: "timestamp")
        } else {
            aes_paramet = paramet
        }
        
        debugPrint(aes_paramet)
        
        var baseUrl = EWEUrl.lgf.baseUrl + method
        baseUrl = baseUrl.replacingOccurrences(of: " ", with: "")
        
        var header = HTTPHeaders()
        header.add(name: "access-token", value: EWEUser.lgf.accessToken ?? "")
        header.add(name: "Accept", value: "application/json")
        
        debugPrint(baseUrl)
        if hud {
            SVProgressHUD.show()
        }
        AF.request(baseUrl, method: type, parameters: aes_paramet, encoding: encoding, headers: header).responseJSON { (response) in
            if hud {
                SVProgressHUD.dismiss()
            }
            switch response.result {
            case .success:
                let json = String(data: response.data!, encoding: String.Encoding.utf8)
                if let result = json?.lgf_ToDictionary() {
                    
                    if let code = result["code"] as? String {
                        if code == "200"  || code == "300"{
                            if let mark = result["mark"] as? Int {
                                if mark == 1 {
                                    if let data = result["data"] as? String {
                                        let key = Data.init(base64Encoded: "8vNlLhwaeIwMExGaM1ou9A==")!
                                        let resultJson = aesDecode(data, key)
                                        let resultData = EVReflection.dictionaryArrayFromJson(resultJson)
                                        if resultData.count > 0 {
                                            debugPrint((method ?? "") + "返回参数 ->")
                                            debugPrint(resultData)
                                            succeed(resultData as AnyObject)
                                        } else {
                                            let resultData = EVReflection.dictionaryFromJson(resultJson)
                                            if resultData.count > 0 {
                                                debugPrint((method ?? "") + "返回参数 ->")
                                                debugPrint(resultData)
                                                succeed(resultData as AnyObject)
                                            } else {
                                                debugPrint((method ?? "") + "返回参数 ->")
                                                debugPrint(resultJson)
                                                succeed(resultJson as AnyObject)
                                            }
                                        }
                                    } else {
                                        mysucceed("" as AnyObject)
                                    }
                                } else {
                                    
                                    debugPrint((method ?? "") + "返回参数 ->")
                                    debugPrint(result["data"])
                                    succeed(result["data"] as AnyObject)
                                }
                            }
                            
                        } else if code == "UNAUTHORIZED" {
                            // 跳转到登录
                            EWEUser.logout()
                            let appDelegate = UIApplication.shared.delegate as! AppDelegate
                            appDelegate.window?.rootViewController = MainNaviVC.init(rootViewController: LoginVC())
                        } else {
                            let err_mes: String =  (result["message"] as? String) ?? "请求失败"
                            myfailure(err_mes)
                        }
                    } else {
                        myfailure("请求失败")
                    }
                } else {
                    let error = response.error
                    if let des = error?.localizedDescription {
                        myfailure(des)
                    } else {
                        myfailure("请求失败")
                    }
                }
            case .failure:
                myfailure("请求失败")
                debugPrint(response.response as Any)
            }
        }
    }
    
    static func uploadFile(_ paths: Any!, _ type: String, _ ex: String, _ isCompressed: Bool = true, _ succeed: @escaping USucceed, _ failed: @escaping Failure) {
        var header = HTTPHeaders()
        header.add(name: "X_Access_Token", value: EWEUser.lgf.accessToken ?? "")
        SVProgressHUD.show()
        AF.upload(multipartFormData: { multipartFormData in
            if let arr = paths as? [String] {
                //数据流
                for (i, v) in arr.enumerated() {
                    if ex == "wav" {
                        do {
                            let wavData = try Data.init(contentsOf: URL.init(fileURLWithPath: v))
                            multipartFormData.append(wavData, withName: "fileList", fileName: "wav" + i.description + ".wav", mimeType: "audio/x-wav")
                        } catch {
                            debugPrint("")
                        }
                    } else if ex == "pdf" {
                        do {
                            let wavData = try Data.init(contentsOf: URL.init(fileURLWithPath: v))
                            multipartFormData.append(wavData, withName: "fileList", fileName: "pdf" + i.description + ".pdf", mimeType: "application/pdf")
                        } catch {
                            debugPrint("")
                        }
                    }
                }
            } else if let images = paths as? [UIImage]  {
                //数据流
                for (i, v) in images.enumerated() {
                    let imageData = v.lgf_ResizeOriginImage().sd_imageData()
                    guard (imageData != nil)  else {
                        failed("图片压缩失败")
                        return
                    }
                    multipartFormData.append(imageData!, withName: "fileList", fileName: "picture" + i.description + ".jpg", mimeType: "image/jpg")
                }
            }
            multipartFormData.append(type.data(using: String.Encoding.utf8)!, withName: "type", mimeType: "text/plain")
        }, to: EWEUrl.lgf.fileUrl, usingThreshold: MultipartFormData.encodingMemoryThreshold,method: .post, headers: header, interceptor: nil, fileManager:.default).responseJSON { (response) in
            SVProgressHUD.dismiss()
            switch response.result {
            case .success:
                let json = String(data: response.data!, encoding: String.Encoding.utf8)
                if let result = json?.lgf_ToDictionary() {
                    if let code = result["code"] as? String {
                        if code == "200" {
                            if let data = result["data"] as? String {
                                succeed(data)
                            } else {
                                failed("上传失败")
                                SVProgressHUD.showError("上传失败")
                            }
                        } else {
                            let err_mes:String =  (result["errmsg"] as? String) ?? "上传失败"
                            failed(err_mes)
                        }
                    } else {
                        failed("上传失败")
                        SVProgressHUD.showError("上传失败")
                    }
                } else {
                    let error = response.error
                    if let des = error?.localizedDescription {
                        failed(des)
                    } else {
                        failed("上传失败")
                        SVProgressHUD.showError("上传失败")
                    }
                }
            case .failure:
                let error = response.error
                if let des = error?.localizedDescription {
                    debugPrint("\(String(describing: des))")
                    failed(des)
                } else {
                    failed("上传失败")
                    SVProgressHUD.showError("上传失败")
                }
            }
        }
    }
    
    static func downloadFile(_ type: String,  _ paramet: [String: Any], _ ex: String, _ isCompressed: Bool = true, _ succeed: @escaping USucceed, _ failed: @escaping Failure) {
        var header = HTTPHeaders()
        header.add(name: "X_Access_Token", value: EWEUser.lgf.accessToken ?? "")
        
        SVProgressHUD.show()
        _ = AF.download(EWEUrl.lgf.baseUrl + "file/" + type, method: .get, parameters: paramet, encoding: URLEncoding.default, headers: header, interceptor: nil) { (request) in
        } to: { (url, response) -> (destinationURL: URL, options: DownloadRequest.Options) in
            return (URL.init(fileURLWithPath: LGF_Documents_Download + "/" + Date().lgf_TimeStampString() + "_" + ex + "." + ex), [.removePreviousFile, .createIntermediateDirectories])
        }.responseURL(completionHandler: { (response) in
            SVProgressHUD.dismiss()
            switch response.result {
            case .success:
                let url = response.value?.absoluteString ?? ""
                succeed(url.replacingOccurrences(of: "file://", with: ""))
            case .failure:
                SVProgressHUD.showError("下载失败")
            }
        })
    }
    
    
    /// AES加密
    ///
    /// - Parameters:
    ///   - content: 待加密内容
    ///   - key: key(与后端保持一致)
    /// - Returns: 加密后内容
    static public func aesEncoded(_ strToEncoded: String, _ key: Data) -> String {
        var encodeString = ""
        do {
            let aes = try AES.init(key: key.bytes, blockMode: ECB.init(), padding: .pkcs7)
            let encoded = try aes.encrypt(strToEncoded.bytes)
            encodeString = encoded.toBase64()!
        } catch  {
            debugPrint(error.localizedDescription)
        }
        return encodeString
    }
    /// AES解密
    ///
    /// - Parameters:
    ///   - strToDecode: 待解密内容
    ///   - key: key(与后端保持一致)
    /// - Returns: 解密后内容
    static public func aesDecode(_ strToDecode: String, _ key: Data) -> String {
        if let data = NSData(base64Encoded: strToDecode, options: NSData.Base64DecodingOptions.init(rawValue: 0)) {
            var decodeStr = ""
            var encrypted: [UInt8] = []
            let count = data.length
            for i in 0..<count {
                var temp:UInt8 = 0
                data.getBytes(&temp, range: NSRange(location: i,length:1 ))
                encrypted.append(temp)
            }
            do {
                let aes = try AES.init(key: key.bytes, blockMode: ECB.init(), padding: .pkcs7)
                let decode = try aes.decrypt(encrypted)
                let encoded = Data(decode)
                decodeStr = String(bytes: encoded.bytes, encoding: .utf8)!
            } catch {
                debugPrint(error.localizedDescription)
            }
            
            return decodeStr
        }
        return strToDecode
    }

}
